package com.myself.module.authority.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.myself.common.define.service.BaseManageService;
import com.myself.common.define.util.CustomJwtUtil;
import com.myself.common.redis.RedisUtil;
import com.myself.module.authority.constant.RedisKeyConstant;
import com.myself.module.authority.mapper.LoginManageMapper;
import com.myself.module.authority.model.UserInfo;
import com.myself.module.authority.mq.producer.email.SendEmailProvider;
import com.myself.module.authority.service.LoginManageService;
import com.myself.module.authority.service.UserInfoService;
import com.myself.module.ci.authority.login.form.GenerateCodeForm;
import com.myself.module.ci.authority.login.form.LoginEmailCode;
import com.myself.module.ci.authority.login.form.LoginPassword;
import com.myself.module.ci.authority.login.form.RegisterForm;
import com.myself.module.ci.authority.login.vo.TokenVo;
import com.myself.source.module.handle.exception.CustomAssert;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;


@Slf4j
@Service
@RequiredArgsConstructor
public class LoginManageServiceImpl implements LoginManageService, BaseManageService {

    private final UserInfoService userInfoService;
    private final LoginManageMapper loginManageMapper;
    private final RedisUtil redisUtil;
    private final SendEmailProvider sendEmailProvider;

    @Override
    public TokenVo generate(String phone) {
        String accessToken = CustomJwtUtil.generateAccessToken(phone);
        String freshToken = CustomJwtUtil.generateRefreshToken(phone);
        return new TokenVo(freshToken, accessToken);
    }


    @Override
    public TokenVo register(RegisterForm form) {
        UserInfo userInfo = BeanUtil.copyProperties(form, UserInfo.class);
        boolean save = userInfoService.save(userInfo);
        CustomAssert.isTrue(save, "用户注册失败，请稍后重试");
        return generate(form.getPhone());
    }

    @Override
    public Boolean generateCode(GenerateCodeForm form) {
        String loginId = form.getLoginId();
        int randomNumber = (int) ((Math.random() * 9 + 1) * 100000);
        boolean set = redisUtil.set(RedisKeyConstant.LOGIN_CODE_PRE, randomNumber);
        if (loginId.contains("@")) {
            sendEmailProvider.sendEmailMessage(loginId, 1L, "经典传媒", "验证码邮件", "验证码为:" + randomNumber);
        } else {
            //TODO 短信待对接
        }
        return set;
    }


    @Override
    public TokenVo checkUserByPassword(LoginPassword form) {
        UserInfo currentUser = loginManageMapper.getUserByPhoneOrEmail(form.getLoginId());
        CustomAssert.notNull(currentUser, "该用户账号不存在");

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(form.getPassword());
        CustomAssert.isTrue(encode.compareTo(currentUser.getPassword()) == 0, "该用户密码不对");

        return generate(currentUser.getPhone());
    }


    @Override
    public TokenVo checkUserByEmailCode(LoginEmailCode form) {
        UserInfo currentUser = loginManageMapper.getUserByPhoneOrEmail(form.getLoginId());
        CustomAssert.notNull(currentUser, "该用户账号不存在");
        Object code = redisUtil.get(RedisKeyConstant.LOGIN_CODE_PRE + form.getLoginId());
        CustomAssert.notNull(code, "验证码已过期请重新过去验证码");
        CustomAssert.isTrue(form.getCode().equals(String.valueOf(code)), "验证码错误");
        return generate(currentUser.getPhone());
    }


}
